% ML TAU 2013 final project script
% Calculate abs(S1 - S2) and perform SVM based on its L to H PCA
% (L*=3 ; H*=120 ; C*=0.250000 ; t*=3 ; deg*=2)

%base_path = '/home/itay/TAU/IML/final';
libsvm_path = './libsvm-3.17/matlab';

% Add path to the libsvm
%addpath(base_path);
addpath(libsvm_path);

%
% Initialization
%
close all; clear; clc; tic;

if ~exist('dataforproject.mat','file')
	error('Data file not found in current directory')
end;

% Saving memory. Loading vars on a need to load basis only throughout
load('dataforproject.mat','X1train','X2train','gidtrain','ytrain', 'X1test', 'X2test');
fprintf('Training data successfully loaded\n');

% Training phase - build the model

% SVM and PCA parameters
% Find the best parameters by running grid_search2.m
L=3 ; H=120 ; c=0.250000 ; t=3 ; d=2;

% We will use abs(X1 - X2) - a very simple distance function
X_TRAIN_DELTA = abs(X1train - X2train);
num_train_entries = size(X_TRAIN_DELTA, 2);

[m,n] = size(X_TRAIN_DELTA);

% Perform PCA - calculate eigenvalues of the covariance matrix
[ EigenVectors, MeanX ] = PerformPCA(X_TRAIN_DELTA, 'X1train-X2train');    

% We will only use PCs L..H
TransformedTrainX = ((X_TRAIN_DELTA - repmat(MeanX, 1, num_train_entries))' * EigenVectors);
TransformedTrainX = TransformedTrainX(:, L:H);

% Now, normalize the data to be within the range of [-1..1]
Minimums = min(TransformedTrainX, [], 1);
Ranges = max(TransformedTrainX, [], 1) - Minimums;
NormalizedTrainX = (2 * (TransformedTrainX - repmat(Minimums, num_train_entries, 1)) ./ repmat(Ranges, num_train_entries, 1)) - 1; 

% Build the model
model = svmtrain(ytrain,NormalizedTrainX,sprintf('-t %d -g 1.0 -c %f -d %d -h 0 -q',t,c,d));

% Test the model using the testing data

load('dataforproject.mat','X1test', 'X2test');
fprintf('Testing data successfully loaded\n');

% Calculate distance matrix
X_TEST_DELTA = abs(X1test - X2test);
num_test_entries = size(X_TEST_DELTA, 2);

% Perform PCA
TransformedTestX = ((X_TEST_DELTA - repmat(MeanX, 1, num_test_entries))' * EigenVectors);
TransformedTestX = TransformedTestX(:, L:H);

% Now, normalize the data to be within the range of [-1..1] using the same value as the training data
NormalizedTestX = (2 * (TransformedTestX - repmat(Minimums, num_test_entries, 1)) ./ repmat(Ranges, num_test_entries, 1)) - 1; 

DummyY = ones(num_test_entries, 1);
ytest = svmpredict(DummyY,NormalizedTestX,model);
save ('ytest.mat', 'ytest');

